You can indeed use authenticated mode as DeepSpace101 suggested, but it has the disadvantage that if the data is large and the last part is e.g. missing that you may not see the difference between missing data and a wrong key being entered. It also slows down the verification as you need to verify all the data before the key can be compared (and no, this will not deter an attacker).
Another method is to use a KCV, most of time a block encrypt of zeros. This has the disadvantage that you don't want to use another block encrypt of zeros; so it is too dangerous in my opinion. You could also use a hash over the key as KCV, but that shows another issue (already present with the previous flawed try): if you reuse the key then the hash will be the same.
So all those things are sub-optimal at best. I'll suggest another one: use a KBKDF such as HKDF and provide a salt and a derived key value with the ciphertext. Use the salt and the input key as input of the KBKDF and calculate the derived value. Then compare it with the derived value stored with the ciphertext. Note that KDF's are irreversible so this should not give an attacker any advantage (but note that the key value is required in memory to do this).
Note that if you want to protect against active attackers you would need to include the salt & hash in the authenticated data (AAD data for authenticated / AEAD ciphers). Of course an active attacker may still let you believe that your data is at fault instead of the key if the key is reused by supplanting a previous salt/derived value - that cannot be avoided.