Sometimes code duplication is the result of a "pun": Two things look the same, but aren't.
It is possible that over-abstracting can break the true modularity of your system. Under the regime of modularity, you have to decide "what is likely to change?" and "what is stable?". Whatever is stable gets put in the interface, while whatever is unstable gets encapsulated in the module's implementation. Then, when things do change, the change you need to make is isolated to that module.
Refactoring is necessary when what you thought was stable (e.g. this API call will always take two arguments) needs to change.
So, for these two duplicated code fragments, I would ask: Does a change required to one necessarily mean the other must be changed as well?
How you answer that question might give you better insight into what a good abstraction might be.
Design patterns are also useful tools. Perhaps your duplicated code is doing a traversal of some form, and the iterator pattern should be applied.
If your duplicated code has multiple return values (and that's why you can't do a simple extract method), then perhaps you should make a class that holds the values returned. The class could call an abstract method for each point that varies between the two code fragments. You would then make two concrete implementations of the class: one for each fragment. [This is effectively the Template Method design pattern, not to be confused with the concept of templates in C++. Alternatively, what you are looking at might be better solved with the Strategy pattern.]
Another natural and useful way to think about it is with higher-order functions. For example, making lambdas or using anonymous inner classes for the code to pass to the abstraction. Generally, you can remove duplication, but unless there really is a relation between them [if one changes, so must the other] then you might be hurting modularity, not helping it.