The codec will do all necessary encoding work when saving data to the file. Thus you can forget about the encoding details and do your work conveniently on strings.
This means: don't do this:
txtEncode = text.encode('utf8')
because type of txtEncode is bytes.
Here is the corrected code:
with codecs.open(filename, 'w', 'utf-8') as o:
text = "I charge it at night & morning."
data = text.replace("&", "&")
o.write(data)
For a simple case like yours, open may be used instead of codecs.open. From the Python3 docs:
While the builtin open() and the associated io module are the
recommended approach for working with encoded text files, this module [i.e. codecs]
provides additional utility functions and classes that allow the use
of a wider range of codecs when working with binary files