How to save modified Texture2D asset in editor code or blueprint?

I had searched for a really long time (several days) unable to find the answer. So of course, immediately after posting this thread, I find the answer here:

While the block of code I posted above doesn’t work on the live mip data, it does work on UTexture2D::Source. You just call LockMip(0) and UnlockMip(0) to write the data. Set the package to dirty and you can save it manually.

So UpdateTextureRegions() to update the live data. And UTexture2D::Source.LockMips() to update the persistent data.