It looks like the problem is that even though the client constructor initialises its members to proper values, the server does not. This causes the server to network “0” for all of its keyfields that aren’t set, and thus causing no emission to happen. The workaround is to set all of the defaults manually serverside:
local smoke = ents.Create("env_smokestack")
smoke:SetSaveValue("InitialState", true) -- Not necessary, but do it to force a start
smoke:SetSaveValue("SpreadSpeed", 15)
smoke:SetSaveValue("Speed", 30)
smoke:SetSaveValue("StartSize", 10)
smoke:SetSaveValue("EndSize", 15)
smoke:SetSaveValue("Rate", 80)
smoke:SetSaveValue("JetLength", 180)
--smoke:SetSaveValue("m_bEmit", true)
smoke:SetSaveValue("BaseSpread", 20)
--smoke:SetSaveValue("Twist", 0)
smoke:SetPos(Entity(1):GetPos())
smoke:Spawn()
smoke:Activate()
Unfortunately, m_AmbientLight and m_DirLight still have incorrect values, but there’s seemingly nothing that can be done about that.