You’re on the right track, but you don’t want to suppress the discount cell of individual items if there’s no item discount. That happens automatically (that is, if there’s no discount for an item, that cell will be left blank for that row).
Get rid of the {% if line.discount != null %} clause. All you need to do is to suppress the entire Discount column if there are no discounts on the entire invoice, which is what the has_discount boolean indicates.
Also, make sure you put the if clause around everything that affects the number of columns in the table, including the header row and the tax-and-total rows on the bottom. (For the latter, you’ll have to change the colspan attribute from 5 to 4 if there’s no discount column in the table. Use if…else…endif surrounding the attribute.) If you don’t do this, the columns won’t line up between the item-list part of the table and the tax-and-totals part of the table.
I can’t see your template, but here is the relevant part of a template that will accomplish what you want (starting at line 51 of the default template template, but you’ll still need to take care of the tax-and-totals part):