I had this particular nightmare after upgrading to iOS 10 and mac OS Sierra, along with other well-documented problems... I found the duplicates refused to disappear even after running the find duplicates feature in the contacts app on my mac and at first thought it was because I'm running an external SSD for the OS firmware. However, all the libraries are pointing in the right direction etc. etc. but found (i.e. got it from someone else) this rather inelegant solution, whilst not signing out of iCloud. Ensure devices have good internet connection:
Turn off contacts in iCloud in Settings on iPhone, when prompted delete contacts on iPhone (at least I did, probably accidentally).
In MacOS look for duplicates in the card tab whilst in-App and merge them - there were over a thousand found on mine but one sweep took care of it but do this on every OSX/MacOS device; I use a MBA as well as iMac and this didn't work at all until done on both computers. Yeah, I know, " all devices should be connected to the internet and "...
Turn on contacts in iCloud settings on iPhone.
Wait a minute or two, as if by magic contacts reappear in the app, call log, messages etc.
Incidentally, on the iPhone I had Contacts found in Apps turned off in Contacts settings, not sure if this makes a difference but I performed this procedure again before posting just to check it wasn't a fluke.
Hope that helps, although most likely it's all figured out now.