This is partly why I've found it helpful to wait until there are at least 3 identical (not nearly identical) implementations of something before trying to make a more generic/abstracted version of it.
I think these rules of thumb are... okay. But I think it's more helpful to go back to how DRY was initially defined ("Every piece of knowledge must have a single, unambiguous, authoritative representation within a system") and ask whether what I'm dealing with is actually "a piece of knowledge." There can be 10 identical copies, and if they just happen to be identical but they represent different things that might change independently, they should probably remain 10 identical, independent copies. Alternatively, if there are exactly two places something occurs in the code, but if they're out of sync the result is a broken system, you should think about unifying.
DRY is too often treated as purely (or principally) syntactic, when that's actually much less useful.
Computers have been widespread for between 70 and 30 years (there is reason to debate, but whatever). Nearly everything has been done before: what you are doing isn't fundamentally new. There is lots of opportunity to add minor new features, reliability, or better user interfaces. But the fundamentals of what you are doing isn't new anymore. You can look at your past versions and what competitors do for guidance on what you will probably need next. If you have any broad knowledge of your problem domain you can make reasonable guesses as to what you will need and what you won't need. When replacing a subsystem I know if there will be 100 users of it in the future or if it is a leaf with 1 user - because I know what the old crufty subsystem has (the first case I spend days thinking about the interface, the second I design the interface when I integrate the one subsystem)