ModelingToolkit is built on Symbolics and SymbolicUtils, that is the place to look for low-level expression manipulation like this. Here is an example (not complete and minimally tested).
using Symbolics
function products(expr)
ex = Symbolics.unwrap(expr)
terms = arguments(ex)
products = filter(terms) do t
istree(t) && ((operation(t) == *) || (operation(t) == ^))
end
end
julia> ex = x * y + z + z*x + y*y
z(t) + x(t)*y(t) + x(t)*z(t) + y(t)^2
julia> products(ex)
3-element Vector{Any}:
x(t)*y(t)
x(t)*z(t)
y(t)^2