There is no reason to free an object if it is already nil (that would be an AV). That causes a part of that memory leak. Another part comes from the string list that is created twice.
Code:
if ColorsHolder nil then
ColorsHolder.Free;
Would make sense but ColorsHolder = nil does not… I rather use Assigned and not Assigned than nil and = nil…