Designing a table with multiple column types and different foreign keys
You can enforce the column nullability based on the template_id by using CHECK CONSTRAINTS, for example:

ALTER TABLE [item] ADD CONSTRAINT CK_Template_Columns
CHECK (
    (template_id = 1 AND usp_1 IS NOT NULL AND icon_1_asset_id IS NOT NULL AND icon_2_asset_id IS NOT NULL AND heading IS NULL AND usp_2 IS NULL)
    OR (template_id = 2 AND heading IS NOT NULL AND icon_1_asset_id IS NOT NULL AND usp_1 IS NULL AND usp_2 IS NULL AND icon_2_asset_id IS NULL)
    OR (template_id = 3 AND usp_1 IS NOT NULL AND usp_2 IS NOT NULL AND heading IS NULL AND icon_asset_1_id IS NULL AND icon_2_asset_id IS NULL)
)


This CHECK CONSTRAINT enforces the columns that cannot be NULL and those that must be NULL based on the chosen template_id. An attempt to fill an invalid column, or leave a valid column blank, for a given template_id would cause the INSERT/UPDATE to fail.

And if you're concerned regarding storage, within SQL Server you have the option of defining SPARSE columns to help reduce storage space for mostly NULL columns. You can also leverage Data Compression and Filtered Indexes to reduce overall space consumption.

For example, a filtered index for each template_id value would allow you to only index the columns that are not null for that template, thereby reducing the number of rows and columns stored in an index.