The factory-factory-factory example reminds me of a certain brand of OO spaghetti, very typical of people who are applying ideas from OOP but don't have a firm grasp of what problem those ideas were meant to solve. I see that problem as distinct from YAGNI, it's just a problem of bad design.
My own advice would be: it's fine to make some shortcuts in the interest of productivity, but please try to keep them isolated. The details of your shortcut shouldn't leak heavily into your design, and the next person to maintain it should be able to swap out pieces without fearing the rest of the thing will fall over.
Over-engineering, architecture astronauts, hurt a system a lot more than someone following YAGNI. Making systems that are a big mess of hard to understand and modify code (even worse). I've seen this happen again and again.
Architects sitting in ivory towers pump out Word documents which result in overly complicated systems. Large, slow, waste people's time and money. The whole idea of "oh, in 10 years we may want to handle this and that" adds unecessary code which then needs to be tested and creates many more points of failure. And did I mention slow? These hairy-balled monstrosities are terribly sow.
If over-engirneers got paid by the line of code, they'd be millionaires. If they got paid for writing elegant, short and easy to maintain code, then they wouldn't have two pennies to rub together -- the YAGNI developer would be sitting in his yacht.
You Ain't Gonna Need It!
My preference is YAGNI while keeping a sharp eye on things that are relatively hard to make extensible later and relatively easy to make extensible now. To tack on another not-great example to the not-great Dog example - if I find myself writing 'dog' a bunch of times in a bunch of ways, I may well pull that out into some sort of `type` variable even if I-ain't-gonna-need-it.
Bloated features are what you just described - more often than not, it's unproductive to code in extra things you don't need on a deadline. You can better work elsewhere. And yet, I think you're right, a lot of developers who will eventually need/want what they're putting in later anyway.
On the other hand, YAGNI has significant security implications. I posted a example downthread about how a database could be compromised by adding in a back-end feature for lazy admins. In that case, YAGNI is really something you want to avoid.
A lean system is an easier system to plug up. But I also understand that's a bit outside the scope of strict features.
And most of the times people mean YAGNI for the first expression of need-vs-implementation. Surely they know there's a lot of chance that one will need more solid abstraction, but it's just to avoid digging too deep into the wrong hole. Somehow it's like http://en.wikipedia.org/wiki/Simulated_annealing . Avoid being stuck in a local maximum.
There's pain in both options: making something specific that has to be made more general later, and making something overly general and never actually having a use for the additional complexity.
The former, though, is solving problems you have, and the latter is solving problems you often don't end up having. Given the choice, I would always prefer the former.
On the contrary, I find that to apply YAGNI successfully, you must think about reuse, or you'll waste a ton of time refactoring all the time and the cost of adding the features you do end up needing will be massive.
I think I've been tainted by too many counter-examples: seeing a piece of code that was specially written for a very narrow and specific use case, and needing to extend it to some scenario that the original author did not envision. If the author hadn't been thinking in terms of re-use and extensibility ("because they ain't gonna need it"), it gets frustrating and regression-prone.
In other words, you ain't gonna need it, until you eventually do. Lazy programmers shouldn't be excused for dismissing maintainability with a simple catch phrase.