About checking for null, there are multiple ways to express it, though they do pretty much the same:
if (GameObject.FindGameObjectWithTag("heroK") != null)
{
newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
}
if (!GameObject.FindGameObjectWithTag("heroK"))
{
newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
}
newtarget = GameObject.FindGameObjectWithTag("heroK")?.GetComponent<Transform>();
Be careful with setting variable first, and checking for null later, as it won't really help you:
newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
// runtime will exit your method prematurely here, as you are trying to call GetComponent on a null
if (newtarget != null) {}
This could help with inactive game objects which is using FindObjectsOfType<T>(true)
But checking for null during start is one thing. You still need to set your target, so you would have to do that periodically, or when the new object is instantiated, which I don't think is really convenient.
I personally would pool (instantiate, and set inactive for future use) all the objects that you are now instantiating during runtime. This way, you could have all objects created beforehand and then set references during their initialization by passing them a list of enemies, or passing them an object that manages the enemies, if the list would be changing a lot.