See also: https://www.swi-prolog.org/pldoc/man?section=text-representation
Atoms: "are identifiers. They are typically used in cases where identity comparison is the main operation and that are typically not composed nor taken apart. Examples are RDF resources (URIs that identify something), system identifiers (e.g., 'Boeing 747'), but also individual words in a natural language processing system. They are also used where other languages would use enumerated types, such as the names of days in the week. Unlike enumerated types, Prolog atoms do not form not a fixed set and the same atom can represent different things in different contexts."
On ambiguities if the system considered '' an atom, see:
Note that in the jargon of logic, the "atom" is actually a predicate symbol associated to its arguments:
p(a,b,c) for example. Not the same. The atom of Prolog (and of LISP) is just a symbol which stands for itself.
A nonempty atom can be quoted or not:
?- atom('a'),atom(a),'a'=a true.
The notation for the empty list  is not an atom, but it is atomic/1 (it is actually a "blob" of type "reserved_symbol"):
?- A=,atom(A). false. ?- A=,atomic(A). A = .
On the other hand, this is just a standard atom of two characters:
?- A='',atom(A). A = ''.
The "empty atom" is an atom:
?- atom(''). true.
The empty atom can appear as a functor, too (don't necessarily use this):
?- Term =.. ['',x,y,z],write_canonical(Term). ''(x,y,z) Term = ''(x, y, z). ?- ''(x,y,z) =.. L. L = ['', x, y, z].
The empty list can appear as functor, too (really weird):
?- Term =.. [,x], Term =.. [F,_], F = . Term = (x), F = .
block operators. I don't get this.