Hi,
first of all you definitely do not want to put the contact received in the INVITE in the 200 OK, since you will, in the best case generate a loop of the UAC sending the ACK to itself.
About having to call msg_apply_changes this comes probably by the fact that you've already manipulated the header with fix_nated_contact(). Due to kamailio's internals you cannot change the headers twice in a row without invoking msg_apply_changes().
For your main problem with the ACK, I'd rather look at the Record-Route. I see in the 200 OK that Record-Route has a private IP. Unless the caller is on the same network or on a network that can communicate with your server, you need to have there a public address (or a double Record-Route if your server is running on two interfaces).
Best regards,
Federico