Double-Click-rename on a list item does not call __setattr__
Your custom __setattr__ method is called if you add or change a collection item via Python (e.g. Python Console). It is not called if you change an entry via the UI.

The reason is probably that bpy properties are no regular python objects / properties. If you access it directly via Python, it is handled like a regular Python object. The UI however is handled in Blender's native C code (so are change events in Blender in general), and it obviously disregards custom __setattr__ handlers.

The proper way to check for property changes is to supply a callback function to the update attribute on property registration, or specify a getter and a setter function.

import bpy
from bpy.props import *

def update_cb(self, context):
    print("image =", self.image)

class RenderGroups(bpy.types.PropertyGroup):
    image = StringProperty(
            name="Image",
            description="The image-texture of this group",
            update=update_cb)


class RenderGroupUIList(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            row = layout.row()
            if not item:
                row.label(text="", translate=False, icon_value=icon)
                return
            row.prop(item, "name", text="", emboss=False, icon_value=icon)
            row.prop(item, "image", text="", emboss=False)
            if item.image not in bpy.data.images:
                row.label(icon="ERROR")
        # 'GRID' layout type should be as compact as possible (typically a single icon!).
        elif self.layout_type in {'GRID'}:
            layout.alignment = 'CENTER'
            layout.label(text="", icon_value=icon)


class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout
        layout.template_list("RenderGroupUIList", "", context.object, "coll", context.object, "idx")


def register():
    bpy.utils.register_module(__name__)
    bpy.types.Object.coll = bpy.props.CollectionProperty(type=bpy.types.RenderGroups)
    bpy.types.Object.idx = bpy.props.IntProperty()


def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.Object.coll
    del bpy.types.Object.idx


if __name__ == "__main__":
    register()


Be careful with writes to the property inside a callback, there is no protection against infinite loops - you need to handle that yourself.

http://www.blender.org/api/blender_python_api_2_73_release/bpy.props.html#get-set-example