From the Wikipedia article on homoiconic
A language is homoiconic if a program written in it can be manipulated as data using the language, and thus the program's internal representation can be inferred just by reading the program itself. This property is often summarized by saying that the language treats "code as data".
My pragmatic take is a language is homoiconic when scripts are themselves valid data types.
There are programming languages that are written in their own AST
More from the wiki article:
One advantage of homoiconicity is that extending the language with new concepts typically becomes simpler, as data representing code can be passed between the meta and base layer of the program. The abstract syntax tree of a function may be composed and manipulated as a data structure in the meta layer, and then evaluated. It can be much easier to understand how to manipulate the code since it can be more easily understood as simple data (since the format of the language itself is as a data format).
Homoiconicity is one of the hallmarks of Lisp, it's the reason why everything is wrapped in parantheses. To be homoiconic means that there is one representation for both data and executable code, that is to say that executable statements are contained within first class data structures. This has a number of benefits, one of which is permitting a Lisp-style macro system.
John McCarthy's original Lisp paper described a LISt Processing language, containing all code and data within S-Expressions. These S-Expressions were lists that, when executed, naturally formed nested call structures. The same is true for data, the lists could be composed to form nested data structures just as they could be composed of nested execution structures.
Elixir, on the surface, is not homoiconic. However, the syntax on the surface is just a facade for the homiconic structure underneath. To peer under the covers we're going to need explore one more of Lisp's ideas.
These concepts feel correlated because ASTs are data structures. Some ASTs are valid data structures in the languages that they are intermediate representations of. Homoiconicity is "programs as data structures". ASTs are programs turned into data structures. The relationship between then two is apparent, but the relationship need not exist for any particular programming language.