The same or very similar code appearing in lots of places is a sign of under-structuredness.
An overly large proportion of structuring code (factories, iterators, meta-programming, etc) to application code is a sign of over-structuredness.
But these are almost truisms. The real answer if it "feels" over or under structured, it is.
The notions of "over-structured" and "under-structured" are highly subjective. A developer who thrives on extensibility, reusability and higher-order programming will tolerate (or expect) much more structure than someone who typically "gets the job done" using cut and paste programming techniques.
The notions are also context dependent. For example, a long lived application is going to need more structure than a throw away prototype, in order to be maintainable in the long term. But, for a prototype, getting the job done is usually more important than getting the structure right. (If the extra structure helps the prototype developer, fine. Otherwise it doesn't matter.) And as @corprow rightly points out, project complexity and team size / maturity are also "contexts" that matter here.
EDIT : IMO, what I wrote equally applies to "over-engineered" versus "under-engineered" as the terms are typically used in IT. However, there are nuances of "over-engineering" that have nothing to do with code structure. For example putting in too many logging points, method/constructor overloads that are never used, writing verbose / useless javadocs, writing voluminous design docs (that are out of date 5 minutes later ... and never updated.)