You are returning a pointer to a array that's already out of scope, that's, wchar_t charHealth[256] belongs to getCharHealth() once it's done running it's undefined behaviour to access the charHealth array again.
What you could try is allocate a dynamic buffer for charHealth and return that instead:
wchar_t *Character::getCharHealth() {
    wchar_t* charHealth = new wchar_t[256];
    swprintf_s(charHealth, L"%d", this->getHealth());
    wprintf(L"%s\n", charHealth);
    return charHealth;
}
You then must remember to delete[] it when no longer needed:
wchar_t* cHealth = warrior->getCharHealth();
spriteFont->DrawString(spriteBatch.get(), cHealth, DirectX::SimpleMath::Vector2(40, 0));
delete[] cHealth;
That's very error prone you might forget to delete[]. Instead you could use std::unique_ptr<wchar_t[]> which automatically deletes the pointer on destruction. That's a technique called RAII if you are no familiar with.
But really, you probably should use a std::wstring with std::to_wstring to convert the number from int to std::wstring, since such a object contains proper string storage optimizations and takes care of any allocation that might be necessary.
std::wstring Character::getCharHealth() {
    std::wstring charHealth = std::to_wstring(this->getHealth());
    wprintf(L"%s\n", charHealth.c_str());
    return charHealth;
}
To access the raw const wchar_t* from a std::wstring you should use the .c_str() method, like so:
spriteFont->DrawString(spriteBatch.get(), warrior->getCharHealth().c_str(), DirectX::SimpleMath::Vector2(40, 0));