This description of problem analysis by Reginald Braithwaite (who is a smart person) struck a chord with me:
I found this to be an important point in my own programming, and I don't know if that's a general point but quite often we see something and we are very tempted to say "Oh, this is a special case of a more general thing", and then we solve the general thing. However that is an infinite recursion, it's always the special case of something more general. And if you are always climbing up the tree into the more general thing you will eventually wind up with a PhD in computer science and no code.
I know one of the areas that I get into trouble sometimes is when I try to make something too meta, too flexible. One of the things we abandoned early on at Xclaim was a very flexible party/roles management system that was so general -- it would have modeled anything -- but it was nigh impossible to represent in as a consistent and meaningful user experience and programming interface (developer experience). I try to stay more mindful, as an applications guy, of my abstractions now and root them in the concrete problem.
For me, learning and flexing DDD was a really useful approach for all sorts of domains and reigning in my tendency to get too abstract. As a method, you can apply it (in part, at least) to really any domain: vertical or horizontal. Patterns such as bounded contexts, intention revealing interfaces, the core pattern language, and ubiquitous language can keep you from falling into the pit of meta-meta-meta-madness.