Use pointers. One pointer i iterates through the array. A second pointer write tracks the position where the next non-zero value should be placed.
When nums[i] is not , swap nums[i] with nums[write], then advance write. When nums[i] is , just advance i.
The write pointer only moves forward when you place a non-zero element. So all zeroes naturally collect at the end. No extra array needed.